React Router: The
Application
Map.
Stop refreshing the whole page. Learn how to switch between views instantly and build multi-page feelings inside a single-page app.
No more white flashes between pages.
Switch views in milliseconds.
Package Installation
Get the Tools
Run this command in your terminal to add the router to your project:
npm install react-router-dom
Single Page Applications (SPA)
The Mental Model
In a traditional site, clicking a link fetches a new HTML file. In an SPA, the page never reloads. React simply swaps components in and out.
Result: It feels like a new page, but you never actually left the first one.
User Experience
Zero Waiting
Navigation happens instantly. No white flashes or waiting for the browser to reload.
Memory retention
Items in a shopping cart or text in a search bar stay exactly where they are as you switch pages.
Routes & BrowserRouter
Visual Component Hierarchy
BrowserRouter
The parent that enables navigation history.
Routes
The container that picks the best matching URL.
How it works
To start routing, you wrap your entire app in the BrowserRouter. This monitors the URL and tells React which component to show based on the path.
import Home from './components/Home';
import About from './components/About';
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
Link & NavLink
The <Link> Tag
Standard
Use this instead of <a> tags. It stops the page from refreshing, keeping your data and state alive.
<Link to="/profile">Profile</Link>
The <NavLink> Tag
SmartSame as Link, but it knows if you are currently on that page. Perfect for highlighing the "Active" button in a menu.
<NavLink className={({ isActive }) => ...} />
Visual Difference
Dynamic Routes & useNavigate
useParams Hook
Access dynamic segments of the URL, like IDs or usernames, to show specific data.
useNavigate Hook
Redirect users after an action (like a form submission or a button click).
const { userId } = useParams();
const navigate = useNavigate();
// Redirect home after clicking
const goHome = () => navigate('/');
return (
<div>
<h1>User ID: {userId}</h1>
<button onClick={goHome}>Back</button>
</div>
);
}
User ID: 99
Content loaded for dynamic param userId
Welcome Home
Navigation triggered via useNavigate()
Nested Routes & <Outlet />
An <Outlet /> is a placeholder. It tells a parent route exactly where to "inject" its child components so they appear inside a shared layout.
import Sidebar from './Sidebar';
export default function DashboardLayout() {
return (
<div className="flex">
<Sidebar />
<main className="p-8">
<Outlet /> // Content
</main>
</div>
);
}
import DashboardLayout from './Layout';
import Home from './Home';
import Profile from './Profile';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<DashboardLayout />}>
<Route index element={<Home />} />
<Route path="profile" element={<Profile />} />
</Route>
</Routes>
</BrowserRouter>
);
}
Protected Routes & Auth
Gatekeeping Content
Create a wrapper component that checks if a user is logged in. If not, use the <Navigate /> component to send them to the login page automatically.
Logic
if (!user) return <Navigate to="/login" />
Success
return <Outlet />
if (!user) {
return <Navigate to="/login" replace />;
}
return <Outlet />;
};